import * as THREE from 'three';
import { Vec3 } from '@/core/types';
import { WorldManager } from '@/world/WorldManager';
import { BlockType } from '@/blocks/types';
import { CollisionSystem } from './CollisionSystem';
import { BlockBreaker } from '@/blocks/BlockBreaker';
import { ItemDropManager } from '@/world/ItemDrop';
import { getAudioManager } from '@/audio/AudioManager';

export class BlockInteraction {
  private worldManager: WorldManager;
  private camera: THREE.PerspectiveCamera;
  private raycaster: THREE.Raycaster;
  private collisionSystem: CollisionSystem;
  private blockBreaker: BlockBreaker;
  private itemDropManager?: ItemDropManager;
  private redstoneManager?: any;
  private reach = 5; // 交互距离

  constructor(worldManager: WorldManager, camera: THREE.PerspectiveCamera, collisionSystem: CollisionSystem) {
    this.worldManager = worldManager;
    this.camera = camera;
    this.collisionSystem = collisionSystem;
    this.raycaster = new THREE.Raycaster();
    this.blockBreaker = new BlockBreaker();
  }

  public setItemDropManager(itemDropManager: ItemDropManager): void {
    this.itemDropManager = itemDropManager;
  }

  public setRedstoneManager(redstoneManager: any): void {
    this.redstoneManager = redstoneManager;
  }

  private notifyBlockBroken(position: Vec3, blockType: BlockType): void {
    // 通知红石系统方块被破坏
    if (this.redstoneManager) {
      this.redstoneManager.onBlockBroken(position, blockType);
    }
  }

  private notifyBlockPlaced(position: Vec3, blockType: BlockType): void {
    // 通知红石系统方块被放置
    if (this.redstoneManager) {
      this.redstoneManager.onBlockPlaced(position, blockType);
    }
  }

  public breakBlock(): boolean {
    const target = this.getTargetBlock();
    if (target) {
      const blockType = this.worldManager.getBlock(target.position);
      
      // 使用方块破坏系统计算掉落物
      const breakResult = this.blockBreaker.breakBlock(blockType);
      
      if (breakResult.success) {
        // 播放方块破坏音效
        this.playBlockBreakSound(blockType, target.position);
        
        // 通知红石系统方块被破坏
        this.notifyBlockBroken(target.position, blockType);
        
        // 移除方块
        this.worldManager.setBlock(target.position, BlockType.AIR);
        
        // 生成掉落物
        if (this.itemDropManager && breakResult.drops.length > 0) {
          for (const drop of breakResult.drops) {
            this.itemDropManager.dropItem(drop.type, drop.count, target.position);
          }
        }
        
        return true;
      }
    }
    return false;
  }

  public placeBlock(blockType: BlockType, playerPosition: Vec3): boolean {
    const target = this.getTargetBlock();
    if (target && target.adjacent) {
      // 检查放置位置是否与玩家碰撞
      if (this.collisionSystem.wouldBlockCollideWithPlayer(target.adjacent, playerPosition)) {
        return false; // 阻止放置，避免玩家被困
      }
      
      this.worldManager.setBlock(target.adjacent, blockType);
      
      // 播放方块放置音效
      this.playBlockPlaceSound(blockType, target.adjacent);
      
      // 通知红石系统方块被放置
      this.notifyBlockPlaced(target.adjacent, blockType);
      
      return true;
    }
    return false;
  }

  private getTargetBlock(): { position: Vec3; adjacent?: Vec3 } | null {
    const direction = new THREE.Vector3();
    this.camera.getWorldDirection(direction);
    
    this.raycaster.set(this.camera.position, direction);
    
    // 逐步检查射线上的每个点
    for (let distance = 0; distance <= this.reach; distance += 0.1) {
      const checkPos = this.camera.position.clone().add(direction.clone().multiplyScalar(distance));
      const blockPos = {
        x: Math.floor(checkPos.x),
        y: Math.floor(checkPos.y),
        z: Math.floor(checkPos.z)
      };
      
      const blockType = this.worldManager.getBlock(blockPos);
      if (blockType > 0) {
        // 找到目标方块，计算相邻位置
        const previousPos = this.camera.position.clone().add(direction.clone().multiplyScalar(distance - 0.1));
        const adjacentPos = {
          x: Math.floor(previousPos.x),
          y: Math.floor(previousPos.y),
          z: Math.floor(previousPos.z)
        };
        
        return {
          position: blockPos,
          adjacent: adjacentPos
        };
      }
    }
    
    return null;
  }

  public getTargetBlockType(): BlockType {
    const target = this.getTargetBlock();
    if (target) {
      return this.worldManager.getBlock(target.position);
    }
    return BlockType.AIR;
  }

  public interactWithBlock(): { blockType: BlockType; position: Vec3 } | null {
    const target = this.getTargetBlock();
    if (target) {
      const blockType = this.worldManager.getBlock(target.position);
      return {
        blockType,
        position: target.position
      };
    }
    return null;
  }

  private playBlockBreakSound(blockType: BlockType, position: Vec3): void {
    const audioManager = getAudioManager();
    const soundId = this.getBlockBreakSoundId(blockType);
    
    if (soundId) {
      audioManager.playSound(soundId, {
        position: position,
        volume: 0.8
      });
    }
  }

  private playBlockPlaceSound(blockType: BlockType, position: Vec3): void {
    const audioManager = getAudioManager();
    
    // 大多数方块使用通用的放置音效
    audioManager.playSound('block_place', {
      position: position,
      volume: 0.6
    });
  }

  private getBlockBreakSoundId(blockType: BlockType): string | null {
    // 根据方块类型返回对应的破坏音效
    switch (blockType) {
      case BlockType.STONE:
      case BlockType.COBBLESTONE:
      case BlockType.COAL_ORE:
      case BlockType.IRON_ORE:
      case BlockType.GOLD_ORE:
      case BlockType.DIAMOND_ORE:
      case BlockType.FURNACE:
        return 'block_break_stone';
      
      case BlockType.LOG:
      case BlockType.BIRCH_LOG:
      case BlockType.SPRUCE_LOG:
      case BlockType.PLANKS:
      case BlockType.CRAFTING_TABLE:
        return 'block_break_wood';
      
      case BlockType.DIRT:
      case BlockType.GRASS:
      case BlockType.SAND:
      case BlockType.GRAVEL:
      case BlockType.CLAY:
        return 'block_break_dirt';
      
      default:
        return 'block_break_stone'; // 默认使用石头音效
    }
  }
}